#include "activityeditor.h"
#include "ui_activityeditor.h"
#include <QFileDialog>
#include <QMessageBox>
#include <QInputDialog>
#include <QJsonDocument>
#include <QJsonParseError>

ActivityEditor::ActivityEditor(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::ActivityEditor)
{
    ui->setupUi(this);
}

ActivityEditor::~ActivityEditor()
{
    delete ui;
}

void ActivityEditor::refreshStu() {
    ui->stuListWid->clear();
    QString queryText = ui->queryStuEdit->text();
    foreach(Student student,students)
        if(student.id.contains(queryText) || student.name.contains(queryText))
            ui->stuListWid->addItem(student.id + "," + student.name);
}

void ActivityEditor::on_queryStuEdit_textChanged(const QString &arg1)
{
    ui->stuListWid->clear();
    foreach(Student student,students)
        if(student.id.contains(arg1) || student.name.contains(arg1))
            ui->stuListWid->addItem(student.id + "," + student.name);
}

void ActivityEditor::updateRecCheckState() {
    ui->recTypeStuWork->setCheckState(recCheckState&studentWork?Qt::Checked:Qt::Unchecked);
    ui->recTypePerDev->setCheckState(recCheckState&personalDevelopment?Qt::Checked:Qt::Unchecked);
    ui->recTypeVolAct->setCheckState(recCheckState&voluntaryActivity?Qt::Checked:Qt::Unchecked);
    ui->recTypePracVis->setCheckState(recCheckState&practiceVisit?Qt::Checked:Qt::Unchecked);
    ui->recTypeComLife->setCheckState(recCheckState&communityLife?Qt::Checked:Qt::Unchecked);
    ui->recTypeAll->setCheckState(recCheckState==allType?Qt::Checked:(recCheckState?Qt::PartiallyChecked:Qt::Unchecked));
}

void ActivityEditor::refreshAct() {
    ui->recListWid->clear();
    ui->recTableWid->clearContents();
    ui->actNameEdit->setText(activity.name);
    ui->actTypeStuWork->setCheckState(activity.type&studentWork?Qt::Checked:Qt::Unchecked);
    ui->actTypePerDev->setCheckState(activity.type&personalDevelopment?Qt::Checked:Qt::Unchecked);
    ui->actTypeVolAct->setCheckState(activity.type&voluntaryActivity?Qt::Checked:Qt::Unchecked);
    ui->actTypePracVis->setCheckState(activity.type&practiceVisit?Qt::Checked:Qt::Unchecked);
    ui->actTypeComLife->setCheckState(activity.type&communityLife?Qt::Checked:Qt::Unchecked);
    ui->actTypeAll->setCheckState(activity.type==allType?Qt::Checked:(activity.type?Qt::PartiallyChecked:Qt::Unchecked));
    ui->recListWid->addItems(activity.records.keys());
    if(activity.records.contains(curRecName)) {
        ui->recNameEdit->setText(curRecName);
        Activity::ActivityRecord record = activity.records[curRecName];
        QStringList idList = record.keys();
        ui->recTableWid->setRowCount(idList.size());
        for(int index=0;index<idList.size();index++) {
            QString id=idList[index];
            ui->recTableWid->setItem(index,0,new QTableWidgetItem(id));
            if(students.contains(id))
                ui->recTableWid->setItem(index,1,new QTableWidgetItem(students[id].name));
            ui->recTableWid->setItem(index,2,new QTableWidgetItem(ActivityTypeNames(record[id].second).join("|")));
            ui->recTableWid->setItem(index,3,new QTableWidgetItem(QString::number(record[id].first)));
        }
    } else {
        curRecName = {};
        ui->recNameEdit->clear();
        ui->actStackedWidget->setCurrentIndex(0);
    }
    ui->creditSpBox->setValue(10);
    recCheckState = allType;
    updateRecCheckState();
    ui->paIDNameEdit->clear();
}
QStringList ActivityEditor::ActivityTypeNames(ActivityType type) {
    QStringList typeNames;
    if(type==noneType) typeNames.append(tr("None"));
    if(type&studentWork) typeNames.append(tr("Student Work"));
    if(type&personalDevelopment) typeNames.append(tr("Personal Development"));
    if(type&practiceVisit) typeNames.append(tr("Practice and Visit"));
    if(type&voluntaryActivity) typeNames.append(tr("Voluntary Activity"));
    if(type&communityLife) typeNames.append(tr("Community Life"));
    return typeNames;
}

void ActivityEditor::on_loadBtn_clicked()
{
    QString Path = QFileDialog::getOpenFileName(this,tr("Select activity record file"),"",tr("Activity record (*.actrec)"));
    if(Path.isEmpty())
        return;
    QFile inf(Path);
    if(!inf.open(QIODevice::ReadOnly)) {
        QMessageBox::warning(this,tr("warning"),tr("Failed while opening activity record!"));
        return;
    }
    QByteArray byteArray=decrypt(inf.readAll());
    inf.close();

    QJsonParseError parseError;
    QJsonDocument doc = QJsonDocument::fromJson(byteArray,&parseError);
    if (doc.isEmpty() || parseError.error != QJsonParseError::NoError) {
        QMessageBox::warning(this,tr("warning"),tr("Failed while parsing activity record!"));
        return;
    }
    QJsonObject object = doc.object();
    if(!activity.parseObj(object)) {
        QMessageBox::warning(this,tr("warning"),tr("Failed while parsing activity record!"));
        return;
    }
    refreshAct();
}


void ActivityEditor::on_saveBtn_clicked()
{
    if(activity.name.isEmpty()) {
        QMessageBox::warning(this,tr("warning"),tr("Activity name should not be empty!"));
        return;
    }
    QString Path = QFileDialog::getSaveFileName(this,tr("Save activity record file"),activity.name+".actrec",tr("Activity record (*.actrec)"));
    if(Path.isEmpty())
        return;
    QFile ouf(Path);
    if(!ouf.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
        QMessageBox::warning(this,tr("warning"),tr("Failed while writing to activity record!"));
        return;
    }

    QJsonDocument doc;
    doc.setObject(activity.getObj());
    ouf.write(encrypt(doc.toJson(QJsonDocument::Compact)));
    ouf.close();
}


void ActivityEditor::on_homeBtn_clicked()
{
    home->show();
    this->destroy();
}


void ActivityEditor::on_actNameEdit_editingFinished()
{
    QString actName = ui->actNameEdit->text();
    activity.name=actName;
    refreshAct();
}


void ActivityEditor::on_actTypeStuWork_clicked(bool checked)
{
    if(checked)
        activity.type = ActivityType(activity.type | studentWork);
    else
        activity.type = ActivityType(activity.type & nStuWorkMask);
    refreshAct();
}


void ActivityEditor::on_actTypePerDev_clicked(bool checked)
{
    if(checked)
        activity.type = ActivityType(activity.type | personalDevelopment);
    else
        activity.type = ActivityType(activity.type & nPerDevMask);
    refreshAct();
}


void ActivityEditor::on_actTypeVolAct_clicked(bool checked)
{
    if(checked)
        activity.type = ActivityType(activity.type | voluntaryActivity);
    else
        activity.type = ActivityType(activity.type & nVolActMask);
    refreshAct();
}


void ActivityEditor::on_actTypePracVis_clicked(bool checked)
{
    if(checked)
        activity.type = ActivityType(activity.type | practiceVisit);
    else
        activity.type = ActivityType(activity.type & nPracVisMask);
    refreshAct();
}


void ActivityEditor::on_actTypeComLife_clicked(bool checked)
{
    if(checked)
        activity.type = ActivityType(activity.type | communityLife);
    else
        activity.type = ActivityType(activity.type & nComLifeMask);
    refreshAct();
}


void ActivityEditor::on_actTypeAll_clicked(bool checked)
{
    if(checked)
        activity.type = allType;
    else
        activity.type = noneType;
    refreshAct();
}


void ActivityEditor::on_recNewBtn_clicked()
{
    QString name = QInputDialog::getText(this, tr("Name input"),tr("Input record name"));
    if(activity.records.contains(name))
        return;
    if(!name.isEmpty())
        activity.records[name]=Activity::ActivityRecord();
    refreshAct();
}


void ActivityEditor::on_recRemBtn_clicked()
{
    QList<QListWidgetItem*> itemList = ui->recListWid->selectedItems();
    foreach(QListWidgetItem* item,itemList) {
        if(activity.records.contains(item->text()))
            activity.records.remove(item->text());
    }
    refreshAct();
}


void ActivityEditor::on_recListWid_itemDoubleClicked(QListWidgetItem *item)
{
    if(!activity.records.contains(item->text())) {
        refreshAct();
        return;
    }
    curRecName = item->text();
    refreshAct();
    ui->actStackedWidget->setCurrentIndex(1);
}


void ActivityEditor::on_recNameEdit_editingFinished()
{
    if(!activity.records.contains(curRecName)) {
        refreshAct();
        return;
    }
    QString newName = ui->recNameEdit->text();
    if(newName == curRecName)
        return;
    if(newName.isEmpty()) {
        ui->recNameEdit->setText(curRecName);
        return;
    }
    if(!activity.records.contains(newName)) {
        Activity::ActivityRecord actRec = activity.records[curRecName];
        activity.records.remove(curRecName);
        curRecName = newName;
        activity.records[newName] = actRec;
        refreshAct();
        return;
    }
    QMessageBox::StandardButton merge = QMessageBox::warning(this,
                                                             tr("Merge Comfirmation"),
                                                             tr("Are you sure to merge records? This operation is not invokable!"),
                                                             QMessageBox::Ok|QMessageBox::Cancel);
    if(merge==QMessageBox::Cancel) {
        ui->recNameEdit->setText(curRecName);
        return;
    }
    foreach(QString id,activity.records[curRecName].keys())
        activity.records[newName][id] = activity.records[curRecName][id];
    activity.records.remove(curRecName);
    curRecName = newName;
    refreshAct();
    return;
}


void ActivityEditor::on_recTypeStuWork_clicked(bool checked)
{
    if(!activity.records.contains(curRecName)) {
        refreshAct();
        return;
    }
    if(checked)
        recCheckState = ActivityType(recCheckState | studentWork);
    else
        recCheckState = ActivityType(recCheckState & nStuWorkMask);
    updateRecCheckState();
}


void ActivityEditor::on_recTypePerDev_clicked(bool checked)
{
    if(!activity.records.contains(curRecName)) {
        refreshAct();
        return;
    }
    if(checked)
        recCheckState = ActivityType(recCheckState | personalDevelopment);
    else
        recCheckState = ActivityType(recCheckState & nPerDevMask);
    updateRecCheckState();
}


void ActivityEditor::on_recTypeVolAct_clicked(bool checked)
{
    if(!activity.records.contains(curRecName)) {
        refreshAct();
        return;
    }
    if(checked)
        recCheckState = ActivityType(recCheckState | voluntaryActivity);
    else
        recCheckState = ActivityType(recCheckState & nVolActMask);
    updateRecCheckState();
}


void ActivityEditor::on_recTypePracVis_clicked(bool checked)
{
    if(!activity.records.contains(curRecName)) {
        refreshAct();
        return;
    }
    if(checked)
        recCheckState = ActivityType(recCheckState | practiceVisit);
    else
        recCheckState = ActivityType(recCheckState & nPracVisMask);
    updateRecCheckState();
}


void ActivityEditor::on_recTypeComLife_clicked(bool checked)
{
    if(!activity.records.contains(curRecName)) {
        refreshAct();
        return;
    }
    if(checked)
        recCheckState = ActivityType(recCheckState | communityLife);
    else
        recCheckState = ActivityType(recCheckState & nComLifeMask);
    updateRecCheckState();
}


void ActivityEditor::on_recTypeAll_clicked(bool checked)
{
    if(!activity.records.contains(curRecName)) {
        refreshAct();
        return;
    }
    if(checked)
        recCheckState = allType;
    else
        recCheckState = noneType;
    updateRecCheckState();
}


void ActivityEditor::on_recTableWid_cellClicked(int row, int column)
{
    if(!activity.records.contains(curRecName)) {
        refreshAct();
        return;
    }
    Activity::ActivityRecord record = activity.records[curRecName];
    QString id = ui->recTableWid->item(row,0)->text();
    if(!record.contains(id)) {
        refreshAct();
        return;
    }
    ui->creditSpBox->setValue(record[id].first);
    recCheckState = record[id].second;
    updateRecCheckState();
}


void ActivityEditor::on_paBatchAddBtn_clicked()
{
    if(!activity.records.contains(curRecName)) {
        refreshAct();
        return;
    }

    QStringList idNameList = ui->paIDNameEdit->toPlainText().split('\n');
    foreach(QString idName,idNameList) {
        CreditRecord rec = {ui->creditSpBox->value(),recCheckState};
        idName.replace("，",",");
        if(idName.contains(',')) {
            QStringList strlist = idName.split(',');
            if(strlist.size()!=2) continue;
            bool ok=false;
            int credit = strlist[1].toInt(&ok);
            if(ok && credit>0) rec.first = credit;
            idName = strlist[0];
        }
        if(isValidId(idName)) {
            activity.records[curRecName][idName]=rec;
        }
        else {
            foreach(Student student,students)
            if(student.name == idName)
            {
                activity.records[curRecName][student.id]=rec;
            }
        }
    }
    refreshAct();
}


void ActivityEditor::on_paRemBtn_clicked()
{
    if(!activity.records.contains(curRecName)) {
        refreshAct();
        return;
    }
    QList<QTableWidgetItem*> itemList = ui->recTableWid->selectedItems();
    QStringList idList;
    foreach(QTableWidgetItem* item,itemList)
        idList.append(ui->recTableWid->item(item->row(),0)->text());
    foreach(QString id,idList)
        if(activity.records[curRecName].contains(id))
            activity.records[curRecName].remove(id);
    refreshAct();
}


void ActivityEditor::on_paUpdBtn_clicked()
{
    if(!activity.records.contains(curRecName)) {
        refreshAct();
        return;
    }
    CreditRecord rec = {ui->creditSpBox->value(),recCheckState};
    QList<QTableWidgetItem*> itemList = ui->recTableWid->selectedItems();
    QStringList idList;
    foreach(QTableWidgetItem* item,itemList)
        idList.append(ui->recTableWid->item(item->row(),0)->text());
    foreach(QString id,idList)
        activity.records[curRecName][id]=rec;
    refreshAct();
}


void ActivityEditor::on_returnBtn_clicked()
{
    ui->actStackedWidget->setCurrentIndex(0);
}

